#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

//模块入口
static int __init dtsof_init(void)
{
	int ret = 0;
	struct device_node *bl_nd;//节点
	struct property    *bl_property;//属性
	int ret_property = 0;
	const char *status_str;
	u32 *ret_property_value = 0;
	u32 elemsize = 0;
	u32 *brival;
	u8 i = 0;
	//找到backlight节点
	bl_nd = of_find_node_by_path("/backlight");
	if(bl_nd == NULL)
	{	
		ret = EINVAL;
		goto fail_find_nd;
	}

	//获取属性
	bl_property = of_find_property(bl_nd,"compatible",NULL);
	if(bl_property == NULL)
	{	
		ret = EINVAL;
		goto fail_find_property;
	}
	else
	{
		printk("compatible:%s\r\n",(char *)bl_property->value);
	}

	ret_property = of_property_read_string(bl_nd,"status",&status_str);
	if(ret_property < 0)
	{
		ret = EINVAL;
		goto fail_find_status;
	}
	else
	{
		printk("status_str:%s\r\n",status_str);
	}
	//数字属性
	ret_property =  of_property_read_u32(bl_nd,"default-brightness-level",&ret_property_value);
	if(ret_property < 0)
	{
		ret = EINVAL;
		goto fail_read32;
	}
	else
	{
		printk("default-brightness-level:%d\r\n",ret_property_value);
	}
	elemsize = of_property_count_elems_of_size(bl_nd,"brightness-levels", sizeof(u32));
	if(elemsize < 0)
	{
		ret = -EINVAL;
		goto fail_read32;
	}
	else
	{
		printk("brightness-levels size:%d\r\n",elemsize);
	}
	//申请内存
	brival = kmalloc(elemsize * sizeof(u32),GFP_KERNEL); //申请动态内存
	if(!brival)
	{
		ret = -EINVAL;
		goto fail_kmalloc;
	}
	//获取数组
	ret_property = of_property_read_u32_array(bl_nd,"brightness-levels",brival,elemsize);
	if(ret_property < 0)
	{
		ret = -EINVAL;
		goto fail_read32_array;
	}
	else
	{
		for (i = 0;i < elemsize;i++)
		{
			//printk("brightness-levels[%d],value:%d\r\n",i,brival[i]);
			printk("brightness-levels[%d],value:%d\r\n",i,*(brival+i));
		}
	}
	kfree(brival);
	return 0;
fail_read32_array:
	kfree(brival);
fail_find_nd:
fail_find_property:
fail_find_status:
fail_read32:
fail_kmalloc:

	printk("error found:\r\n");
	return ret;
}

//模块出口
static void __exit dtsof_exit(void)
{

}

/*模块入口和出口 */
module_init(dtsof_init);
module_exit(dtsof_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eason");
